Imports System.ComponentModel
Imports System.Drawing.Drawing2D
Imports System.Windows.Forms

<Designer(GetType(XPanderDesigner)), DesignTimeVisibleAttribute(True)> _
Public Class XPander
    Inherits System.Windows.Forms.UserControl

#Region " Constants "
    Private Const c_ExpandCollapseHeight As Integer = 1
    Private Const c_ExpandCollapseAlpha As Integer = 2
#End Region

    Private m_CaptionHeight As Integer = 25
    Private m_CaptionText As String = ""
    Private m_CaptionTextColor As Color = Color.FromArgb(33, 93, 198)
    Private m_CaptionTextHighlightColor As Color = Color.FromArgb(66, 142, 255)
    Private m_CaptionFont As New Font("Microsoft Sans Serif", 8, FontStyle.Bold)
    Private m_CaptionColor As Color = Color.FromArgb(198, 210, 248)
    Private m_Expanded As Boolean = True
    Private m_ExpandedAtLoad As Boolean = True
    Private m_IsCaptionHighlighted As Boolean = False
    Private m_Height As Integer

    Private m_Images(4) As Bitmap

#Region " Custom Events "
    ' Repeatedly fired as the XPander is being collapsed
    Delegate Sub XPanderCollapsingHandler(ByVal x As XPander, ByVal delta As Integer)
    Public Event XPanderCollapsing As XPanderCollapsingHandler

    ' Fired when the XPander is completely collapsed
    Delegate Sub XPanderCollapsedHandler(ByVal x As XPander)
    Public Event XPanderCollapsed As XPanderCollapsedHandler

    Delegate Sub XPanderExpandingHandler(ByVal x As XPander, ByVal delta As Integer)
    Public Event XPanderExpanding As XPanderCollapsingHandler

    Delegate Sub XPanderExpandedHandler(ByVal x As XPander)
    Public Event XPanderExpanded As XPanderExpandedHandler
#End Region

#Region " Windows Form Designer generated code "

    Public Sub New()
        MyBase.New()

        'This call is required by the Windows Form Designer.
        InitializeComponent()

        'Add any initialization after the InitializeComponent() call
        ' We draw everything, and repaint when resized.
        SetStyle(ControlStyles.ResizeRedraw, True)
        SetStyle(ControlStyles.AllPaintingInWmPaint, True)
        SetStyle(ControlStyles.UserPaint, True)
        SetStyle(ControlStyles.DoubleBuffer, True)
        SetStyle(ControlStyles.SupportsTransparentBackColor, True)
        SetStyle(ControlStyles.ContainerControl, True)

        Me.BackColor = Color.FromArgb(214, 223, 247) ' Default
    End Sub

    'UserControl overrides dispose to clean up the component list.
    Protected Overloads Overrides Sub Dispose(ByVal disposing As Boolean)
        If disposing Then
            If Not (components Is Nothing) Then
                components.Dispose()
            End If
        End If
        MyBase.Dispose(disposing)
    End Sub

    'Required by the Windows Form Designer
    Private components As System.ComponentModel.IContainer

    'NOTE: The following procedure is required by the Windows Form Designer
    'It can be modified using the Windows Form Designer.  
    'Do not modify it using the code editor.
    <System.Diagnostics.DebuggerStepThrough()> Private Sub InitializeComponent()
        Me.SuspendLayout()
        '
        'XPander
        '
        Me.Name = "XPander"
        Me.Size = New System.Drawing.Size(8, 136)
        Me.ResumeLayout(False)

    End Sub

#End Region

#Region " Public Properties "
    ' properties
    <Description("Height of caption."), _
    DefaultValue(25), _
    Category("Appearance")> _
    Public Property CaptionHeight() As Integer
        Get
            Return m_CaptionHeight
        End Get

        Set(ByVal Value As Integer)
            m_CaptionHeight = Value
            Invalidate()
        End Set
    End Property

    <Description("Caption text."), _
    DefaultValue(""), _
    Category("Appearance"), _
    Localizable(True)> _
    Public Property CaptionText() As String
        Get
            Return m_CaptionText
        End Get

        Set(ByVal Value As String)
            m_CaptionText = Value
            Invalidate()
        End Set
    End Property

    <Description("Caption color."), _
    DefaultValue("180,190,240"), _
    Category("Appearance")> _
    Public Property CaptionColor() As Color
        Get
            Return m_CaptionColor
        End Get

        Set(ByVal Value As Color)
            m_CaptionColor = Value
            Invalidate()
        End Set
    End Property

    <Description("Caption text color."), _
    DefaultValue("33,93,198"), _
    Category("Appearance")> _
    Public Property CaptionTextColor() As Color
        Get
            Return m_CaptionTextColor
        End Get

        Set(ByVal Value As Color)
            m_CaptionTextColor = Value
            Invalidate()
        End Set
    End Property

    <Description("Caption text color when the mouse is hovering over it."), _
    DefaultValue("66, 142, 255"), _
    Category("Appearance")> _
    Public Property CaptionTextHighlightColor() As Color
        Get
            Return m_CaptionTextHighlightColor
        End Get

        Set(ByVal Value As Color)
            m_CaptionTextHighlightColor = Value
            Invalidate()
        End Set
    End Property

    <Description("Caption font."), _
    Category("Appearance")> _
    Public Property CaptionFont() As Font
        Get
            Return m_CaptionFont
        End Get

        Set(ByVal Value As Font)
            m_CaptionFont = Value
            Invalidate()
        End Set
    End Property

    '<Description("Expanded state of control at load time."), _
    ' DefaultValue("True"), _
    ' DesignOnly(True), _
    ' Category("Appearance")> _
    'Public Property ExpandedAtLoad() As Boolean
    '    Get
    '        Return m_ExpandedAtLoad
    '    End Get
    '    Set(ByVal Value As Boolean)
    '        m_ExpandedAtLoad = Value
    '        ChangeHeight()
    '        'Invalidate()
    '    End Set
    'End Property

    <Browsable(False), _
     DesignOnly(True)> _
    Public Property ExpandedHeight() As Integer
        Get
            Return m_Height
        End Get
        Set(ByVal Value As Integer)
            m_Height = Value
        End Set
    End Property
#End Region

    Private Sub XPander_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.Load

        LoadImages()

        Me.DockPadding.Top = m_CaptionHeight
    End Sub

    Private Sub LoadImages()
        ' Load images from the .dll
        m_Images(1) = New Bitmap(Me.GetType(), "Collapse.jpg")
        m_Images(2) = New Bitmap(Me.GetType(), "Collapse_h.jpg")
        m_Images(3) = New Bitmap(Me.GetType(), "Expand.jpg")
        m_Images(4) = New Bitmap(Me.GetType(), "Expand_h.jpg")
    End Sub

    Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
        Dim rc As New Rectangle(0, 0, Me.Width, CaptionHeight)
        Dim strX As Single
        Dim b As New LinearGradientBrush(rc, Color.White, CaptionColor, _
         LinearGradientMode.Horizontal)
        Dim size As Size = e.Graphics.MeasureString(CaptionText, CaptionFont).ToSize()

        If Me.RightToLeft Then
            b = New LinearGradientBrush(rc, CaptionColor, Color.White, _
             LinearGradientMode.Horizontal)
        End If

        ' Now draw the caption areas with the rounded corners at the top
        e.Graphics.FillRectangle(b, rc)

        ' Draw the outline around the work area
        If Me.Height > m_CaptionHeight Then
            e.Graphics.DrawLine(New Pen(Color.FromKnownColor(KnownColor.HighlightText)), _
                0, Me.CaptionHeight, 0, Me.Height)
            e.Graphics.DrawLine(New Pen(Color.FromKnownColor(KnownColor.HighlightText)), _
                Me.Width - 1, Me.CaptionHeight, Me.Width - 1, Me.Height)
            e.Graphics.DrawLine(New Pen(Color.FromKnownColor(KnownColor.HighlightText)), _
                0, Me.Height - 1, Me.Width - 1, Me.Height - 1)
        End If

        ' Caption text.
        If Me.RightToLeft Then
            strX = Me.Width - size.Width - 10
        Else
            strX = CSng(10)
        End If

        If m_IsCaptionHighlighted Then
            e.Graphics.DrawString(CaptionText, CaptionFont, New SolidBrush(m_CaptionTextHighlightColor), _
             strX, CSng((Me.CaptionHeight - 2 - size.Height) / 2))
        Else
            e.Graphics.DrawString(CaptionText, CaptionFont, New SolidBrush(m_CaptionTextColor), _
             strX, CSng((Me.CaptionHeight - 2 - size.Height) / 2))
        End If

        If m_Images(1) Is Nothing Then
            LoadImages()
        End If

        ' Expand / Collapse Icon
        Dim icon1X As Integer
        Dim icon2X As Integer
        If Me.RightToLeft Then
            icon1X = 8
            icon2X = 8
        Else
            icon1X = Me.Width - m_Images(1).Width - 8
            'icon1X = Me.Width - ImageList1.Images(0).Width - 8
            icon2X = Me.Width - m_Images(2).Width - 8
            'icon2X = Me.Width - ImageList1.Images(1).Width - 8
        End If


        If m_Expanded Then
            If m_IsCaptionHighlighted Then
                e.Graphics.DrawImage(m_Images(2), icon1X, 4)
                'e.Graphics.DrawImage(ImageList1.Images(1), icon1X, 4)
            Else
                e.Graphics.DrawImage(m_Images(1), icon1X, 4)
                'e.Graphics.DrawImage(ImageList1.Images(0), icon1X, 4)
            End If
        Else
            If m_IsCaptionHighlighted Then
                e.Graphics.DrawImage(m_Images(4), icon2X, 3)
                'e.Graphics.DrawImage(ImageList1.Images(3), icon2X, 3)
            Else
                e.Graphics.DrawImage(m_Images(3), icon2X, 3)
                'e.Graphics.DrawImage(ImageList1.Images(2), icon2X, 3)
            End If
        End If
    End Sub

    Protected Overrides Sub OnMouseMove(ByVal e As System.Windows.Forms.MouseEventArgs)
        ' Change cursor to hand when over caption area.
        If e.Y <= Me.CaptionHeight Then
            Cursor.Current = Cursors.Hand
            m_IsCaptionHighlighted = True
        Else
            Cursor.Current = Cursors.Default
            m_IsCaptionHighlighted = False
        End If
        Invalidate()
    End Sub

    Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
        ' Don't do anything if did not click on caption.
        If e.Y > Me.CaptionHeight Then
            Return
        End If

        ' Toggle expanded flag.
        m_Expanded = Not m_Expanded

        ' Expand or collapse the control based on its current state
        ChangeHeight()
        Me.Refresh()
    End Sub

    Protected Overrides Sub OnMouseLeave(ByVal e As System.EventArgs)
        If m_IsCaptionHighlighted Then
            m_IsCaptionHighlighted = False
            Invalidate()
        End If
    End Sub

    Private Sub ChangeHeight()
        If Not m_Expanded Then
            ' Remember height so we can restore it later.
            m_Height = Me.Height

            ' Set the new height and let others know we have been collapsed
            Me.Height = CaptionHeight
            RaiseEvent XPanderCollapsed(Me)
        Else
            Me.Height = m_Height
            RaiseEvent XPanderExpanded(Me)
        End If
    End Sub

    Public Sub Expand()
        If Not m_Expanded Then
            m_Expanded = True
            ChangeHeight()
        End If
    End Sub

    Public Sub Collapse()
        If m_Expanded Then
            m_Expanded = False
            ChangeHeight()
        End If
    End Sub

    Public ReadOnly Property IsExpanded()
        Get
            Return m_Expanded
        End Get
    End Property
End Class
